//==========================================================================
// Copyright (c) 2000-2006,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <eltypes.h>
#include <elasys_server.h>
#include <RTC.h>
#include <stdio.h>

ECode CRTC::Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode  CRTC::Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CRTC::Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf *pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent)
{
    ECode ec = NOERROR;
    switch(nControlCode) {
        case 0: {//enable rtc alarm,default:enabled
            ec = RTCEnableAlarm();
            break;
        }
        case 1: {//disable rtc alarm
            ec = RTCDisableAlarm();
            break;
        }
        case 2: {//get rtc time info
            int h, m, s;
            if(pOutBuffer->GetCapacity()<12)return E_INVALID_ARGUMENT;
            ec = RTCReadTime(&h, &m, &s);
            pOutBuffer->Copy((Byte *)&h,4);
            pOutBuffer->Append((Byte *)&m,4);
            pOutBuffer->Append((Byte *)&s,4);
            pOutBuffer->SetUsed(12);
            break;
        }
        case 3: {//get rtc date info
            int w, y, mt, d;
            if(pOutBuffer->GetCapacity()<16)return E_INVALID_ARGUMENT;
            ec = RTCReadDate(&w, &y, &mt, &d);
            pOutBuffer->Copy((Byte *)&w,4);
            pOutBuffer->Append((Byte *)&y,4);
            pOutBuffer->Append((Byte *)&mt,4);
            pOutBuffer->Append((Byte *)&d,4);
            pOutBuffer->SetUsed(16);
            break;
        }
        case 4://get rtc alarm time info,
        {
            int ha, ma, sa;
            if(pOutBuffer->GetCapacity()<12)return E_INVALID_ARGUMENT;
            ec = RTCReadAlarmTime(&ha, &ma, &sa);
            pOutBuffer->Copy((Byte *)&ha,4);
            pOutBuffer->Append((Byte *)&ma,4);
            pOutBuffer->Append((Byte *)&sa,4);
            pOutBuffer->SetUsed(12);
            break;
        }
        case 5:{//get rtc alarm date info
            int wa, ya, mta, da;
            if(pOutBuffer->GetCapacity()<16)return E_INVALID_ARGUMENT;
            ec = RTCReadAlarmDate(&wa, &ya, &mta, &da);
            pOutBuffer->Copy((Byte *)&wa,4);
            pOutBuffer->Append((Byte *)&ya,4);
            pOutBuffer->Append((Byte *)&mta,4);
            pOutBuffer->Append((Byte *)&da,4);
            pOutBuffer->SetUsed(16);
            break;
        }
        case 6://set rtc time info
        {
            if(inBuffer.GetCapacity()<12)return E_INVALID_ARGUMENT;
            int * p = (int *)(char *)inBuffer.GetPayload();
            ec = RTCSettime(p[0],p[1],p[2]);
            break;
        }
        case 7://set rtc date info
        {
            if(inBuffer.GetCapacity()<16)return E_INVALID_ARGUMENT;
            int * p = (int *)(char *)inBuffer.GetPayload();
            ec = RTCSetdate(p[0],p[1],p[2],p[3]);
            break;
        }
        case 8://set rtc alarm time
        {
            if(inBuffer.GetCapacity()<12)return E_INVALID_ARGUMENT;
            int * p = (int *)(char *)inBuffer.GetPayload();
            RTCSetAlarmtime(p[0],p[1],p[2]);
            break;
        }
        case 9://set rtc alarm date
        {
            if(inBuffer.GetCapacity()<16)return E_INVALID_ARGUMENT;
            int * p = (int *)(char *)inBuffer.GetPayload();
            ec = RTCSetAlarmdate(p[0],p[1],p[2],p[3]);
            break;
        }
        case 10://set rtc date & time
        {
            if(inBuffer.GetCapacity()<(int)sizeof(SystemTime))return E_INVALID_ARGUMENT;
            ec = RTCSetdatetime((SystemTime *)(char *)inBuffer.GetPayload());
            break;
        }
        default :break;
    }
    return ec;
}

void CRTC::Init()
{
    RTCInit();
}

void CRTC::Dispose()
{
    RTCDispose();
}

static CRTC s_pRTC;

EXTERN IDeviceDriver * CDECL CreateRTC(uint_t uDeviceNo, void *pvParameter)
{
    s_pRTC.Init();
    return (IDeviceDriver *)&s_pRTC;
}

